<template>
  <zm-view ref="view" background="#f4f6f7" @auth-success="reload">
    <!-- 顶部座位类型 -->

    <scroll-view scroll-x class="area-wrap">
      <view class="area-list">
        <view v-for="(item, index) in seatTypes" :key="index" class="area-item">
          <image class="desc-icon" :src="item.icon" mode="heightFix"></image>
          <text>{{ item.name }}</text>
        </view>
      </view>
    </scroll-view>
    <!-- 选座区 -->
    <cinema-seat-select
      ref="seatSelect"
      :move-area-height="moveAreaHeight"
      :limit="limit"
      :data="seatInfo"
      :sessions="sessions"
      :seat-icon-options="seatIconOptions"
      :plan-key="planKey"
      @select="handleSelectSeat"
    ></cinema-seat-select>
    <view class="footer">
      <!-- 底部确认信息 -->
      <view v-if="$check.isNoEmpty(seatInfo)" class="confim-wrap">
        <view v-if="notices.length" class="flex items-center pb-14 mb-30 solid-bottom-2">
          <u-notice-bar
            custom-style="padding: 0"
            icon="volume-fill"
            :icon-color="useColor('theme')"
            bg-color="#fffff"
            color="#666"
            font-size="24rpx"
            :text="notices"
            direction="column"
            @click="showNoticePopup = true"
          ></u-notice-bar>
          <zm-icon-text
            name="arrow"
            color="#999"
            weight="bold"
            text-color="#666"
            text-left
            :text="notices.length > 1 ? `${notices.length}个通知` : ''"
            custom-class="ml-24 click-animation"
            @click="showNoticePopup = true"
          ></zm-icon-text>
        </view>
        <view class="flex items-center justify-between">
          <text class="font-28 font-bold">{{ seatInfo.planInfo.filmName }}</text>
          <view class="flex items-center" @click="handleClickExpand">
            <text class="expand-btn mr-14">{{ expanded ? "收起" : "切换" }}场次</text>
            <view class="transition" :class="{ 'transform-rotate-180': expanded }">
              <u-icon name="arrow-up" color="#3F94F5" size="24rpx"></u-icon>
            </view>
          </view>
        </view>
        <view class="flex font-26 mt-16">
          <text class="mr-12" :style="[useThemeStyle()]">{{ seatInfo.planInfo.sDate | formatDayWeekDesc }}</text>
          <text class="text-666 whitespace-nowrap">
            {{ seatInfo.planInfo.sDate | formatDate("MM月DD日") }} {{ session.sTime }}-{{ session.eTime }} {{ seatInfo.planInfo.copyLanguage }}{{ seatInfo.planInfo.copyType }}
          </text>
        </view>
        <!-- 场次列表 -->
        <view class="session-wrap" :class="{ 'is-expand': expanded }">
          <scroll-view :scroll-x="true" class="scroll-wrap mt-16">
            <view class="flex">
              <view
                v-for="(item, index) in sessions"
                :key="index"
                class="session-item transition"
                :class="{ 'is-active': item.planKey === planKey }"
                :style="[useThemeRGBAStyle()]"
                @click="handleClickSession(item)"
              >
                <text class="font-28 font-bold">{{ item.sTime }}</text>
                <text class="text-row-1 font-22 text-999">{{ item.copyLanguage }}{{ item.copyType }}</text>
                <text class="font-22 text-price-before">{{ item.areaMinPrice || item.salePrice }}</text>
              </view>
            </view>
          </scroll-view>
        </view>
        <view v-if="selectSeats.length" class="mt-30 pt-24 solid-top-2">
          <scroll-view :scroll-x="true" class="scroll-wrap">
            <view class="flex">
              <view v-for="item in selectSeats" :key="item.seatNo" class="seat-item">
                <view class="flex flex-col">
                  <text class="font-24">{{ item.seatPieceName }}</text>
                  <text class="font-22 text-price text-price-before">{{ item.salePrice }}</text>
                </view>
                <view class="delete-btn" @click="removeSeats(item)">
                  <u-icon name="close" color="#999999" size="24rpx"></u-icon>
                </view>
              </view>
            </view>
          </scroll-view>
        </view>
      </view>
      <!-- 确定按钮 -->
      <view class="flex p-24">
        <zm-button type="primary" :disabled="btnDisable" size="large" round width="100%" height="100rpx" @click="submit">{{ btnText }}</zm-button>
      </view>
    </view>

    <!-- 提示场次时间和隔空选座 -->
    <zm-toast ref="toast">
      <view class="flex items-center">
        <image v-if="toastType == 1" class="gap-warn-icon" :src="useImage('/zuimei-film-oss/1.0.0/images/gap-seat-warn.png')" mode="scaleToFill" />
        <view v-if="toastType == 2" class="flex items-center"> <text>您选择的场次将在 </text> <text :style="[useThemeStyle()]">30分钟内</text> <text> 开场，请留意时间</text> </view>
        <view v-if="toastType == 3" class="flex items-center">
          <text>您选择的是 </text> <text :style="[useThemeStyle()]">{{ seatInfo.planInfo.sDate | formatDayWeekDesc }}{{ seatInfo.planInfo.sDate | formatDate("MM月DD日") }}</text>
          <text> 场次</text>
        </view>
      </view>
    </zm-toast>
    <!-- 公告弹框 -->
    <zm-popup :show.sync="showNoticePopup" mode="bottom" border-radius="24rpx" closeable>
      <view slot="header" class="p-32 font-32 font-bold text-center">观影小贴士</view>
      <view class="px-35 pb-24">
        <view v-for="(item, index) in notices" :key="index" class="notice-text">{{ item }}</view>
      </view>
      <view class="p-24">
        <zm-button size="large" @click="showNoticePopup = false">我知道了</zm-button>
      </view>
    </zm-popup>
  </zm-view>
</template>

<script>
import page from "@/mixins/page"
import hook from "@/mixins/hook"
import CinemaSeatSelect from "./components/cinema-seat-select"
import { mapGetters, mapActions } from "vuex"
import { baseImageUrl } from "@/config"
export default {
  components: { CinemaSeatSelect },
  mixins: [page, hook],
  data() {
    return {
      moveAreaHeight: 300,
      isExistSeat: true, // 是否存在座位
      expanded: false,
      planKey: "",
      cinemaId: "",
      activityId: "",
      seatInfo: {},
      cinemaInfo: {},
      notices: [],
      showNoticePopup: false,
      session: { sTime: "", eTime: "" },
      sessions: [],
      seatOptions: {},
      limit: 4, // 最大可选座位数
      seatIconOptions: {
        disable: `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/disable.png`, // 不可销售图标
        double: `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/double.png`, // 情侣座图标
        select: `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/select.png`, // 选中单人图标
        "select-double": `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/select-double.png`, // 选中双人图标
        sold: `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/sold.png`, // 已售单人图标
        "sold-double": `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/sold-double.png` // 已售双人图标
      },
      seatTypes: [], // 座位介绍
      areas: [], // 区域信息
      selectSeats: [], // 已选座位
      toastLock: false,
      toastType: 1 // 1隔空选座 / 2开场时间小于30 / 3不是同一天
    }
  },
  computed: {
    ...mapGetters(["realNameAg", "realNameStatus", "userInfo", "themeColor", "channelInfo"]),
    // 底部按钮显示
    btnText() {
      if (this.selectSeats.length == 0) return "请先选座"
      return `￥${this.totalPrice} 确认选座`
    },
    // 支付按钮状态
    btnDisable() {
      if (!this.isExistSeat) return false
      return this.selectSeats.length == 0
    },
    // 需要支付的总价
    totalPrice() {
      let sum = 0
      this.selectSeats.map((item) => {
        console.log(item)
        sum = this.$u.plus(sum, item.salePrice)
      })
      return sum
    }
  },
  onLoad(options) {
    this.planKey = options.planKey
    this.cinemaId = options.cinemaId
    this.activityId = options.activityId || ""
    this.seatIconOptions.sold = this.channelInfo?.seatIcon || `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/sold.png`
    this.seatIconOptions["sold-double"] = this.channelInfo?.doubleSeatIcon || `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/sold-double.png`
    this.init()
  },
  onShow() {
    if (uni.$leaveRoute == "pages/pay/sure-order/sure-order") {
      this.cancelSeatLock()
    }
    // 用于获取最新的锁座号码
    this.$store.dispatch("getUserInfo")

    // window.history.pushState(null, null, document.URL)
    // window.addEventListener("popstate", this.onBack, false)
  },
  watch: {
    // 小程序回退阻止
    //  #ifdef MP-WEIXIN || MP-TOUTIAO || MP-ALIPAY
    selectSeats: {
      handler() {
        this.selectSeats.length > 0 ? uni.$enableAlertBeforeUnload("确定不要刚才选择的座位了吗？") : uni.$disableAlertBeforeUnload()
      },
      deep: true
    }
    // #endif
  },
  methods: {
    // onBack() {
    //   //检测到返回再插一条
    //   window.history.pushState(null, null, document.URL)
    //   //在这里弹个弹框什么的
    //   console.log(1)
    // },
    reload() {
      this.init()
    },
    async init() {
      await this.handleGetPlanSeat()
      this.handleGetCinemaDes()
      this.handleGetPlanHeadDateList()
    },
    // 计算座位图容器高度
    getMoveAreaHeight() {
      this.$nextTick(async () => {
        const footerRect = await this.useRect(".footer")
        const wrapRect = await this.useRect(".area-wrap")
        this.moveAreaHeight = uni.$u.sys().windowHeight - footerRect.height - wrapRect.height
      })
    },
    async handleGetPlanSeat() {
      try {
        this.selectSeats = []
        this.seatInfo = await uni.$api.plan.getPlanSeat({ planKey: this.planKey, cinemaId: this.cinemaId, activityId: this.activityId }, { handleError: false })
        this.openTimeJudge(this.seatInfo.planInfo)
        this.hasOrderInfo()
        this.areas = this.seatInfo.planInfo.areas?.length ? this.seatInfo.planInfo.areas : [{ salePrice: this.seatInfo.planInfo.salePrice, areaId: "default" }]
        this.handleGenSeatDescs()
        this.isExistSeat = this.seatInfo.seatInfos.some((row) => row.some((col) => col.seatState == 0))
        if (!this.isExistSeat) {
          uni.$toast("本场座位已满，换个场次吧")
        }
      } catch (err) {
        if (err.status == "10005") {
          const route = this.useCurrentRoute()
          uni.$toast("用户未登录，请先登录")
          uni.$emit(`${route}-login`)
        } else {
          uni.$dialog({
            title: "提示",
            content: err.content || err.message,
            onConfirm: () => {
              this.selectSeats = []
              uni.navigateBack()
            }
          })
        }
      }
    },
    async handleGetCinemaDes() {
      this.cinemaInfo = await uni.$api.cinema.getCinemaDes({ cinemaId: this.cinemaId })
      this.notices = this.cinemaInfo.notice.map((item) => item.notice)
    },
    handleGetPlanHeadDateList() {
      uni.$api.plan
        .planHeadDateList({ planKey: this.planKey, cinemaId: this.cinemaId, activityId: this.activityId }, { handleError: false })
        .then((res) => {
          const find = res.find((item) => item.sDate === this.seatInfo.planInfo.sDate)
          this.sessions = find?.list
          this.planKey = this.seatInfo.planInfo.planKey
          if (this.sessions.length) {
            this.session = this.sessions.find((item) => item.planKey === this.planKey)
          }
          this.getMoveAreaHeight()
        })
        .catch((err) => {
          if (err.status == "10005") {
            const route = this.useCurrentRoute()
            uni.$toast("用户未登录，请先登录")
            uni.$emit(`${route}-login`)
          } else {
            uni.$dialog({
              title: "提示",
              content: err.content || err.message,
              onConfirm: () => {
                uni.navigateBack()
              }
            })
          }
        })
    },
    // 取消锁座
    async cancelSeatLock() {
      const seatInfo = await uni.$api.plan.getPlanSeat({ planKey: this.planKey, cinemaId: this.cinemaId, activityId: this.activityId }, { handleError: false })
      if (uni.$getCache("time-out")) {
        uni.$setCache("time-out", false)
        this.selectSeats = []
        this.$refs.seatSelect.resetSeat()
        this.$forceUpdate()
      }
      seatInfo.oldOrderId && seatInfo.oldOrderId != "0" && uni.$api.orderFilm.unLockSeat({ orderId: seatInfo.oldOrderId })
    },
    // 判断是否存在待支付订单
    hasOrderInfo() {
      if (this.seatInfo.oldOrderId != "0") {
        // 存在未支付订单
        const query = { orderId: this.seatInfo.oldOrderId }
        uni.$dialog({
          title: "提示",
          content: "您有一笔未支付的订单",
          cancelButtonText: "取消订单",
          confirmButtonText: "去支付",
          asyncClose: true,
          showConfirmButton: true,
          showCancelButton: true,
          onConfirm: ({ close }) => {
            if (this.seatInfo.lockJumpPay) {
              close()
              this.useAskToOSSJump(this.seatInfo.lockJumpPay)
            } else {
              close()
              this.resetOrderInfo()
              this.toView({
                url: `pages/order/order-film-info/order-film-info`,
                type: "reLaunch",
                params: {
                  orderId: this.seatInfo.oldOrderId,
                  activityId: this.activityId,
                  cinemaId: this.cinemaId
                }
              })
            }
          },
          onCancel: ({ close }) => {
            close()
            uni.$toast("正在取消锁座")
            uni.$api.orderFilm
              .unLockSeat(query)
              .then(() => {
                setTimeout(() => {
                  uni.hideToast()
                  this.selectSeats = []
                  this.$refs.seatSelect.resetSeat()
                  this.$forceUpdate()
                  uni.$toast({ type: "success", content: "操作成功" })
                  this.init()
                }, 300)
              })
              .catch(() => {
                uni.hideToast()
              })
          }
        })
      }
    },
    // 处理选座
    async handleSelectSeat(list) {
      const map = this.areas.reduce((map, item) => ({ ...map, [item.areaId]: item.salePrice }), {})
      this.selectSeats = list.map((item) => {
        return { ...item, salePrice: +map[item.areaId] || +map["default"] }
      })
      if (this.selectSeats.length > 0) {
        this.expanded = false
      }
    },
    // 点击场次
    async handleClickSession(data) {
      this.session = data
      this.openTimeJudge(data)
      this.selectSeats = []
      this.$forceUpdate()
      this.planKey = data.planKey
      await this.handleGetPlanSeat()
    },
    openTimeJudge(data) {
      // 场次开始时间小于30分钟提示
      if (uni.$formatDayWeekDesc(data.sDate) == "今天") {
        const nowDateTime = uni.$formatTime(new Date(), "YYYY-MM-DD HH:mm:ss")
        const sDateTime = `${data.sDate} ${data.sTime}:00`
        const { hours, minutes } = uni.$diffDate(nowDateTime, sDateTime)
        if (hours == 0 && minutes < 30) {
          this.toastType = 2
          this.$refs.toast.show({ offset: 120, position: "top", duration: 5000 })
        }
      } else if (!this.toastLock) {
        this.toastLock = true
        this.toastType = 3
        this.$refs.toast.show({ offset: 120, position: "top", duration: 5000 })
      }
    },
    // 点击展开
    handleClickExpand() {
      this.expanded = !this.expanded
    },
    // 生成座位类型
    handleGenSeatDescs() {
      const list = [
        { icon: this.seatIconOptions["disable"], name: "不可售" },
        { icon: this.seatIconOptions["sold"], name: "已售" },
        ...this.areas.map((item, index) => {
          return { icon: `${baseImageUrl}/zuimei-film-oss/1.0.0/seat/type-${index}.png`, name: item.salePrice }
        })
      ]
      const isExistDouble = this.seatInfo.seatInfos.some((item) => item.some((subItem) => subItem.seatType === "L" || subItem.seatType === "R"))
      if (isExistDouble) list.push({ icon: this.seatIconOptions["double"], name: "情侣座" })
      this.seatTypes = list
    },
    // 取消选座
    removeSeats(item) {
      this.$refs.seatSelect.cancelSeat(item.seatNo)
    },
    // 提交信息锁座
    submit() {
      if (this.$refs.seatSelect.judgeChoose()) {
        this.lockSeat()
      } else {
        this.toastType = 1
        this.$refs.toast.show({ background: "transparent" })
      }
    },
    // 执行锁座方法
    async lockSeat() {
      const seatList = this.selectSeats.map((item) => {
        const seatItem = {
          hallNo: item.hallNo,
          seatNo: item.seatNo,
          seatPieceName: item.seatPieceName,
          ticketPrice: item.ticketPrice,
          serviceAddFee: item.serviceAddFee,
          salePrice: item.salePrice
        }
        return seatItem
      })
      const data = {
        cinemaId: this.cinemaId,
        planKey: this.planKey,
        seatList: JSON.stringify(seatList),
        lockMobile: this.userInfo.lockMobile || this.userInfo.bindingMobile,
        activityId: this.activityId,
        frontUrl: "/pages/outPay/outPay"
      }
      uni.$toast("座位锁定中,正在前往支付页")

      uni.$api.orderFilm
        .lockSeat(data, { login: false, handleError: false })
        .then((res) => {
          uni.hideToast()
          this.resetOrderInfo()
          this.toView({
            url: "pages/pay/sure-order/sure-order",
            params: { orderId: res.orderId, cinemaId: this.cinemaId, activityId: this.activityId }
          })
        })
        .catch((err) => {
          uni.hideToast()
          // 锁坐失败
          uni.$toast(err.content || err.message)
          setTimeout(() => this.handleGetPlanSeat(), 2000)
        })
    },
    resetOrderInfo() {
      uni.$setCache("payStatus", 0)
      this.clearOrderInfo()
    },
    ...mapActions(["clearOrderInfo"])
  }
}
</script>

<style lang="scss" scoped>
.area-wrap {
  display: flex;
  padding: 0 60rpx;
  text-align: center;
  .area-list {
    display: inline-flex;
    padding: 34rpx 0 20rpx 0;
    .area-item {
      display: flex;
      align-items: center;
      margin-right: 24rpx;
      &:last-child {
        margin-right: 0;
      }
      .desc-icon {
        height: 32rpx;
        margin-right: 10rpx;
      }
    }
  }
}
.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 3;
}
.confim-wrap {
  margin: 0 24rpx;
  padding: 24rpx;
  background: #ffffff;
  border-radius: 16rpx;
  box-shadow: 0rpx 1rpx 10rpx 1rpx rgba(103, 103, 103, 0.16);

  .expand-btn {
    color: #3f94f5;
  }

  .scroll-wrap {
    width: calc(100vw - 24rpx * 4);
  }

  .session-wrap {
    height: 0;
    display: grid;
    overflow: hidden;
    transition: all 0.3s ease;

    &.is-expand {
      height: 146rpx;
    }

    .session-item {
      width: 140rpx;
      height: 130rpx;
      width: 140rpx;
      padding: 12rpx;
      display: flex;
      margin-right: 12rpx;
      border-radius: 10rpx;
      flex-direction: column;
      justify-content: space-between;
      border: 2rpx solid transparent;

      &.is-active {
        border-color: var(--theme-color);
      }
    }
  }

  .seat-item {
    height: 78rpx;
    padding: 12rpx;
    display: flex;
    padding-right: 0;
    margin-right: 20rpx;
    align-items: center;
    background: #f4f6f7;
    border-radius: 10rpx;
    justify-content: space-between;

    .delete-btn {
      padding-left: 18rpx;
      padding-right: 18rpx;
      border-left: 1rpx solid #eeeeee;
    }
  }
}

.gap-warn-icon {
  width: 382rpx;
  height: 280rpx;
  margin-bottom: 140rpx;
}

.notice-text {
  color: #666;
  font-size: 26rpx;
  padding-left: 32rpx;
  line-height: 36rpx;
  margin-bottom: 45rpx;
  position: relative;

  &::after {
    left: 0;
    top: 12rpx;
    width: 12rpx;
    height: 12rpx;
    border-radius: 50%;
    position: absolute;
    content: "";
    background-color: var(--theme-color);
  }
}
</style>
